package cn.boodqian.airreport;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.Assert;

import com.google.gson.*;

import cn.boodqian.airreport.AirreportActivity.MyGestureDetectorListener;
import cn.boodqian.util.*;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.animation.AnimationUtils;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

public class AirreportProfileActivity extends Activity implements  OnGroupClickListener  {
	private GAERequest mAirdataRequest = new GAERequest(GlobalData.gGAEProject);
	private ArrayList<HashMap<String, String>> mProfiles = new ArrayList<HashMap<String,String>>();
	private Gson mGson = new Gson();
	private Handler handler = new ServerMessageHandler();
	private ExpandableListView mListProfile;
	private HistoryView mHistoryView;
	private TextView mTextHistoryTitle;
	private ColorAdapter mProfileAdapter = null;
	private GlobalData mGlobalData = null;
	private GestureDetector mGestureDetector = new GestureDetector(new MyGestureDetectorListener());;
	
	private boolean ignoreNextClick = false;
	private int[] mTips = new int[] {R.string.app_name, R.string.tip_1, R.string.tip_2, R.string.tip_3}; 
	
	private final int ADD_PROFILE_REQUEST_CODE=0;
	private ArrayList<ArrayList<HashMap<String, String>>> mDetailDataList = new ArrayList<ArrayList<HashMap<String,String>>>();
	private ViewFlipper mFlipper;
	
	class MyGestureDetectorListener extends SimpleOnGestureListener {
		private static final int FLING_MIN_DISTANCE = 80;
		private static final int FLING_MAX_DISTANCE = 200;
		private static final int FLING_THRESHOLD_VELOCITY = 200;

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			float scale = getResources().getDisplayMetrics().densityDpi;
			if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE*scale/160f
					&& Math.abs(velocityX) > FLING_THRESHOLD_VELOCITY*scale/160f) {
				if(!AirreportProfileActivity.this.onFling(e1, e2)) return false;
				
				mFlipper.setInAnimation(AnimationUtils.loadAnimation(
						AirreportProfileActivity.this, R.anim.slide_right_in));
				mFlipper.setOutAnimation(AnimationUtils.loadAnimation(
						AirreportProfileActivity.this, R.anim.slide_left_out));
				mFlipper.showNext();
				return true;
			} else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE*scale/160f
					&& Math.abs(velocityX) > FLING_THRESHOLD_VELOCITY*scale/160f) {
				if(!AirreportProfileActivity.this.onFling(e1, e2)) return false;
				
				mFlipper.setInAnimation(AnimationUtils.loadAnimation(
						AirreportProfileActivity.this, R.anim.slide_left_in));
				mFlipper.setOutAnimation(AnimationUtils.loadAnimation(
						AirreportProfileActivity.this, R.anim.slide_right_out));
				mFlipper.showPrevious();
				return true;
			}
			return false;
		}
	}
	
	private class ColorAdapter extends SimpleExpandableListAdapter {

		public ColorAdapter(Context context,
				List<? extends Map<String, ?>> groupData, int groupLayout,
				String[] groupFrom, int[] groupTo,
				List<? extends List<? extends Map<String, ?>>> childData,
				int childLayout, String[] childFrom, int[] childTo) {
			super(context, groupData, groupLayout, groupFrom, groupTo, childData,
					childLayout, childFrom, childTo);
		}

		@Override
		public View getGroupView(int position, boolean isExpanded, View convertView, ViewGroup parent) {
			View view = super.getGroupView(position, isExpanded, convertView, parent);
			Map<String, String> map = (Map<String, String>) this.getGroup(position);
			
			TextView aqiView = (TextView)view.findViewById(R.id.text_aqi);
			TextView aqidescView = (TextView)view.findViewById(R.id.text_aqi_desc);
			
			if( map.get("id").length() == 0 ) {
				return view;
			}
			
			Integer aqi = 0;
			Float cc = 0f;
			try {
				aqi = Integer.parseInt(map.get("aqi_value"));
				cc = Float.parseFloat(map.get("cc_value"));
			} catch(NumberFormatException e) {
				// do nothing
			}
			if( cc.compareTo(0f) == 0 ) {
				aqiView.setTextColor( Color.GRAY );
			} else {
				aqiView.setTextColor( Color.parseColor(AQI.AQIColor(aqi)) );
				aqidescView.setTextColor( Color.parseColor(AQI.AQIColor(aqi)) );
			}

			return view;
		}

		@Override
		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			View view =  super.getChildView(groupPosition, childPosition, isLastChild,
					convertView, parent);
			
			TextView nowView = (TextView)view.findViewById(R.id.text_realtime_value);
			TextView avgView = (TextView)view.findViewById(R.id.text_avg24_value);
			
			Map<String, String> map = (Map<String, String>) this.getChild(groupPosition, childPosition);
			
			Integer aqi_now = 0;
			Float cc_now = 0f;
			Integer aqi_avg = 0;
			Float cc_avg = 0f;
			
			try {
				aqi_now = Integer.parseInt(map.get("aqi_now"));
				cc_now = Float.parseFloat(map.get("cc_now"));
				aqi_avg = Integer.parseInt(map.get("aqi_avg"));
				cc_avg = Float.parseFloat(map.get("cc_avg"));
			} catch(NumberFormatException e) {
				// do nothing
			}
			
			if( cc_now.compareTo(0f) == 0 ) {
				nowView.setTextColor( Color.GRAY );
			} else {
				nowView.setTextColor( Color.parseColor(AQI.AQIColor(aqi_now)) );
			}
			
			if( cc_avg.compareTo(0f) == 0 ) {
				avgView.setTextColor( Color.GRAY );
			} else {
				avgView.setTextColor( Color.parseColor(AQI.AQIColor(aqi_avg)) );
			}
			
			return view;
		}
	}
	
		class ServerMessageHandler extends Handler {
		/* (non-Javadoc)
		 * @see android.os.Handler#handleMessage(android.os.Message)
		 */
		@Override
		public void handleMessage(Message msg) {
			long when = System.currentTimeMillis();
			int currentVersion = mGlobalData.getVersionCode();
			int messageVersion = 0;
			int savedLastServerMessageCode = mGlobalData.gLastServerMessageCode;
			long savedLastUpdateMessageTime = mGlobalData.gLastUpdateMessageTime;
			Float lockWeight = 0f;
			try{
				HashMap<String, String> map = (HashMap<String, String>)msg.obj;
				for(String x:map.keySet()) {
					Log.d("Key="+x+", Bytes:"+x.getBytes());
				}
				
				messageVersion = Integer.parseInt(map.get("version"));
				Log.i(String.format("Server Message rcv, %d (%d)", messageVersion, currentVersion));
				
				if(currentVersion>messageVersion) return;
				
				String message = null;
				String title = null;
				int messageCode=0;
				if(currentVersion<messageVersion) {
					// When version below, show 'update' field
					title = AirreportProfileActivity.this.getString(R.string.server_update);
					message = map.get("update");
					
					// Only display update message once a day
					if( mGlobalData.gLastUpdateMessageTime/864000000 == when/864000000) return;
					mGlobalData.gLastUpdateMessageTime = when;
				} else {
					// When version matches, show 'message' field
					title = AirreportProfileActivity.this.getString(R.string.server_message);
					message = map.get("message");
					String str = map.get("message-code");
					if(str!=null)
						messageCode = Integer.parseInt(str);
					
					Log.i(String.format("message-code: old %d new %d", mGlobalData.gLastServerMessageCode, messageCode));
					
					// Only display message with higher code
					if(mGlobalData.gLastServerMessageCode >= messageCode) return;
					mGlobalData.gLastServerMessageCode = messageCode;
				}
				if(message==null || message.compareTo("")==0) return;
				
				Intent intent = new Intent(AirreportProfileActivity.this, ServerMessageActivity.class);
				intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
				intent.putExtra("title", title);
				intent.putExtra("message", message);
				PendingIntent contentIntent = PendingIntent.getActivity(AirreportProfileActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT );
				Notification notification = new Notification(cn.boodqian.airreport.R.drawable.ic_launcher, title, when);
				notification.flags = Notification.FLAG_AUTO_CANCEL;
				NotificationManager nm = (NotificationManager) AirreportProfileActivity.this.getSystemService(NOTIFICATION_SERVICE);
				notification.setLatestEventInfo(AirreportProfileActivity.this, title, message, contentIntent);

				nm.notify(1, notification);
			} catch (Exception e) {
				if(currentVersion == messageVersion)
					mGlobalData.gLastServerMessageCode = savedLastServerMessageCode;
				else
					mGlobalData.gLastUpdateMessageTime = savedLastUpdateMessageTime;
				e.printStackTrace();
			}
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.flipper);
		
		mListProfile = (ExpandableListView) findViewById(R.id.list_profile);
		mListProfile.setOnGroupClickListener(this);
		
		mTextHistoryTitle = (TextView) findViewById(R.id.history_view_title);
		mHistoryView = (HistoryView) findViewById(R.id.history_view);
		mFlipper = (ViewFlipper) findViewById(R.id.flipper);
		
		registerForContextMenu(mListProfile);
		
		final ProgressDialog dlg = ProgressDialog.show(this,
				getString(R.string.refresh_wait),
				getString(R.string.restore_data), true);
		
		mGlobalData = GlobalData.getNewInstance(this);
		Thread t = new Thread() {
			public void run() {
				mGlobalData.restorePrefs();
				handler.post(new Runnable() {
					public void run() {
						dlg.dismiss();
						mGlobalData.updateAirdata(mGlobalData.gProfileList.toArray(new String[]{}), new Runnable(){
							public void run() {
								if( mGlobalData.gIsFirstRun ) {
									showUsage();
								}
								updateProfileListUI();
							}
						});
					};
				});
			}
		};
		t.start();
		
		// Show tip in title bar
		setTitle(getString(R.string.app_name) + " - " + getString(R.string.tip_help));
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		
		mGlobalData.savePrefs();
	}

	private void updateProfileListUI()
	{
		if(mProfiles == null) {
			Log.w("mProfiles  is null");
			return;
		}
		
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd HH:mm");
		
		mProfiles.clear();
		mDetailDataList.clear();
		for(String id : mGlobalData.gProfileList) {
			HashMap<String, String> location = mGlobalData.getLocationInfo(id);
			if(location == null) continue;
			if( id.compareTo(location.get("id")) == 0) {
				// For group items (profile data)
				Object[] max_pollutant = mGlobalData.getMaxPollutant(id);
				Integer aqi_value = (Integer)max_pollutant[1];
				Float cc_value = (Float)max_pollutant[2];
				HashMap<String, String> profile_item_data = new HashMap<String, String>();
				profile_item_data.putAll(location);
				profile_item_data.put("aqi_value", aqi_value.toString());
				profile_item_data.put("cc_value", cc_value.toString());
				Date lastupdate = mGlobalData.gAirdataHash.get(id).getTime();
				profile_item_data.put("time",
						lastupdate!=null ? fmt.format(lastupdate) : ""
						);
				profile_item_data.put("aqi_text",
						( cc_value.compareTo(0f)==0 ) ?
								getString(R.string.not_available) :
									String.format("%.1fµg/%d", cc_value*1000, aqi_value)
						);
				profile_item_data.put("aqi_desc",
						( cc_value.compareTo(0f)==0 ) ? "" : getString(AQI.AQICategory(aqi_value))
						);
				mProfiles.add(profile_item_data);
				
				// For child items (detail data)
				AirData airdata = mGlobalData.gAirdataHash.get(id);
				Assert.assertTrue( id, airdata != null );
				
				ArrayList<HashMap<String,String>> childDataList = new ArrayList<HashMap<String,String>>();
				for(String name : GlobalData.gItemNameList) {
					HashMap<String,String> map1 = new HashMap<String, String>();
					List<Float>data = airdata.getData(name);
					if( data != null && data.size()>0) {
						Float cc_now = data.get(data.size()-1);
						Integer aqi_now = AQI.getAQI(name, cc_now);
						Float cc_avg = mGlobalData.calcAverage(id, name);
						Integer aqi_avg = AQI.getAQI(name, cc_avg);
						
						map1.put("cc_now", cc_now.toString());
						map1.put("aqi_now", aqi_now.toString());
						map1.put("cc_avg", cc_now.toString());
						map1.put("aqi_avg", aqi_avg.toString());
						
						map1.put("name", GlobalData.getPollutantDisplayName(name));
						map1.put("realtime",
								(cc_now.compareTo(0f)==0) ?
										getString(R.string.not_available)
										: String.format("%.1f/%03d:%s", cc_now*1000, aqi_now, getString(AQI.AQICategory(aqi_now))));
						map1.put("avg24",
								(cc_avg.compareTo(0f)==0) ?
										getString(R.string.not_available)
										: String.format("%.1f/%03d:%s", cc_avg*1000, aqi_avg, getString(AQI.AQICategory(aqi_avg))));
						childDataList.add(map1);
					}
				}
				
				mDetailDataList.add(childDataList);
			}
		}

		HashMap<String, String> map = new HashMap<String, String>();
		map.put("id", "");
		map.put("city", "");
		map.put("name",  getString(R.string.profile_hint));
		map.put("aqi_text", "");
		map.put("aqi_desc", "");
		mProfiles.add(map);
		
		mDetailDataList.add(new ArrayList<HashMap<String,String>>());

		mProfileAdapter = new ColorAdapter(this,
				mProfiles, R.layout.profile_item,
				new String[]{"city", "name", "time", "aqi_text", "aqi_desc"},
				new int[]{R.id.text_city, R.id.text_name, R.id.text_time, R.id.text_aqi, R.id.text_aqi_desc},
				mDetailDataList, R.layout.airdata_detail_item,
				new String[]{"name", "realtime", "avg24"},
				new int[]{R.id.text_dataitem, R.id.text_realtime_value, R.id.text_avg24_value});
		mListProfile.setAdapter(mProfileAdapter);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		
		switch(requestCode) {
		case ADD_PROFILE_REQUEST_CODE:
			String newId = null;
			// data will be null if "back" pressed without selection
			if(  data != null && (newId = data.getStringExtra("id")) != null ) {
				mGlobalData.gProfileList.add(newId);
				mGlobalData.updateAirdata(new String[] {newId}, new Runnable(){
					public void run() {
						updateProfileListUI();
					}
				});
			}
			break;
		}
	}

	@Override
	public boolean onGroupClick(ExpandableListView parent, View v,
			int groupPosition, long id) {
		if( ignoreNextClick ) {
			ignoreNextClick = false;
			return true;
		}
		HashMap<String,String> map = (HashMap<String, String>)parent.getItemAtPosition(groupPosition);
		switch(parent.getId()) {
		case R.id.list_profile:
			// Seems map[id] will be null sometimes, not sure why yet
			if( map.get("id") != null && map.get("id").length()==0) {
				// Add a new profile
				Intent intent = new Intent(getApplicationContext(),
						LocationSelectActivity.class);
				startActivityForResult(intent, ADD_PROFILE_REQUEST_CODE);
				return true;
			}
			break;
		default:
			break;
		}
		return false;
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		
		ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
		int type  = ExpandableListView.getPackedPositionType(info.packedPosition);
		int group = ExpandableListView.getPackedPositionGroup(info.packedPosition);
		int child = ExpandableListView.getPackedPositionChild(info.packedPosition);
		
		if( type == ExpandableListView.PACKED_POSITION_TYPE_GROUP ) {
			MenuInflater inflater = getMenuInflater();
			inflater.inflate(R.menu.data_context, menu);
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		ExpandableListContextMenuInfo info = 
				(ExpandableListContextMenuInfo) item.getMenuInfo();

		int groupPos = 0, childPos = 0;

		int type = ExpandableListView.getPackedPositionType(info.packedPosition);
		if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) 
		{
			groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
			childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);
		}
		
		HashMap<String, String> map = mProfiles.get(groupPos);
		String locId = map.get("id");

		switch (item.getItemId()) 
		{
		case R.id.menu_remove:
			// Remove all
			while( mGlobalData.gProfileList.remove(locId) );
			updateProfileListUI();
			return true;

		case R.id.menu_share:
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd HH:mm");
			Object[] max_pollutant = mGlobalData.getMaxPollutant(locId);
			String airType = mGlobalData.getPollutantDisplayName(max_pollutant[0].toString());
			Integer aqi_value = (Integer)max_pollutant[1];
			Float cc_value = (Float)max_pollutant[2]*1000;
			Date time = mGlobalData.gAirdataHash.get(locId).getTime();
			String city = map.get("city");
			String locName = map.get("name");
			String msg = String.format( getString(R.string.share_message),
					getString(R.string.app_name),
					(( time == null ) ? "" : fmt.format(time)),
					city+locName,
					airType,
					cc_value,
					aqi_value,
					(( cc_value.compareTo(0f)==0 ) ? "" : getString(AQI.AQICategory(aqi_value))),
					(( cc_value.compareTo(0f)==0 ) ? "" : getString(AQI.AQIAdvisory(aqi_value))) );
				
			Intent share = new Intent(Intent.ACTION_SEND);
			share.setType("text/plain");
			share.putExtra(Intent.EXTRA_TEXT, msg);
			startActivity(Intent.createChooser(share, "Share Text"));

			return true;
			
		case R.id.menu_refresh:
			mGlobalData.updateAirdata(mGlobalData.gProfileList.toArray(new String[]{}), new Runnable(){
				public void run() {
					updateProfileListUI();
				}
			});
			return true;
			
		case R.id.menu_history:
			prepareHistoryView(locId, map.get("name"));
			mFlipper.setInAnimation(AnimationUtils.loadAnimation(
					AirreportProfileActivity.this, R.anim.slide_right_in));
			mFlipper.setOutAnimation(AnimationUtils.loadAnimation(
					AirreportProfileActivity.this, R.anim.slide_left_out));
			mFlipper.showNext();
			return true;

		default:
			return super.onContextItemSelected(item);
		}
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev){
		super.dispatchTouchEvent(ev);    
		return mGestureDetector.onTouchEvent(ev); 
	}
	
	private void prepareHistoryView(String locId, String locName) {
		Log.i("HistoryView of " + locId + "/" + locName);
			
		AirData airdata = mGlobalData.gAirdataHash.get(locId);
		if( airdata == null || airdata.getLength() == 0 || airdata.getTime() == null ) {
			Log.e("Location " + locId + " has invalid data");
			return;
		}

		mTextHistoryTitle.setText( locName + " - " + getString(R.string.history) );

		List<String> marks = new ArrayList<String>();
		int length = Math.min(24, airdata.getLength());
		int lastHour = airdata.getTime().getHours();
		for( int i = 0; i < length; i++) {
			int hour = lastHour - i;
			if(hour<0) hour+=24;
			marks.add(0, String.format("%02d", hour));
		}

		mHistoryView.clearHistoryData();
		mHistoryView.setHorizonMark(marks);

		for(String pollutant : GlobalData.gItemNameList) {
			List<Float> ccList = airdata.getData(pollutant); 
			if(  ccList == null ) continue;

			List<Float> aqiList = new ArrayList<Float>();
			for( Float cc : ccList ) {
				aqiList.add( (float)AQI.getAQI(pollutant, cc) );
			}
			mHistoryView.addHistoryData(
					aqiList,
					(int)GlobalData.getPollutantDisplayColor(pollutant),
					GlobalData.getPollutantDisplayName(pollutant)
					);
		}
		mHistoryView.invalidate();
	}
	
	private boolean onFling( MotionEvent e1, MotionEvent e2 ) {
		if( mFlipper.getDisplayedChild() != 0 ) {
			// Possibly switch back, so retore it
			ignoreNextClick = false;
			return true;
		}
		
		int[] point = new int[2];
		mListProfile.getLocationOnScreen(point);
		Log.i("View: "+point[0]+","+point[1]);
		Log.i("Motion: "+(int)e1.getRawX()+","+(int)e1.getRawY());
		point[0] = (int)e1.getRawX() - point[0];
		point[1] = (int)e1.getRawY() - point[1];
		if( point[0]>0 || point[1]>0) {
			// Prevent the "tap up" expand any group
			ignoreNextClick = true;

			long packedPosition = mListProfile.getExpandableListPosition(mListProfile.pointToPosition(point[0], point[1]));
			int type  = ExpandableListView.getPackedPositionType(packedPosition);
			int group = ExpandableListView.getPackedPositionGroup(packedPosition);
			int child = ExpandableListView.getPackedPositionChild(packedPosition);

			if( type == ExpandableListView.PACKED_POSITION_TYPE_GROUP ||
					type == ExpandableListView.PACKED_POSITION_TYPE_CHILD ) {
				if( group < mProfiles.size() - 1 ) {
					HashMap<String, String> map = mProfiles.get(group);
					prepareHistoryView(map.get("id"), map.get("name"));
					return true;
				}
			}
		}
		
		Toast.makeText(
				this,
				getString(R.string.tip_flip),
				Toast.LENGTH_LONG).show();
		return false;
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		
		if(false) {
			// For debug on emulator
			//new ServerMessageTask(handler, packageInfo.versionName).execute("http://10.0.2.2:3000/airreport");
		} else {
			new ServerMessageTask(handler, mGlobalData.getVersionName()).execute(getString(R.string.update_url));
		}
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.airreport, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case R.id.menu_refresh:
			mGlobalData.updateAirdata(mGlobalData.gProfileList.toArray(new String[]{}), new Runnable(){
				public void run() {
					updateProfileListUI();
				}
			});
			return true;
		case R.id.menu_usage:
			showUsage();
			return true;
		case R.id.menu_clearall:
			AlertDialog.Builder b = new AlertDialog.Builder(this).setTitle(getString(R.string.clearall));
			b.setMessage(getString(R.string.clearall_confirm));
			b.setPositiveButton(getString(android.R.string.yes), new DialogInterface.OnClickListener(){
				@Override
				public void onClick(DialogInterface dialog, int which) {
					mGlobalData.clearAll();
					updateProfileListUI();
				}
			});
			b.setNegativeButton(getString(android.R.string.cancel), null);
			b.show();
			return true;
		case R.id.menu_feedback:
			final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
			String title = String.format(getString(R.string.feedback_title), getString(R.string.app_name), mGlobalData.getVersionName());
			emailIntent .setType("message/rfc822");
			//emailIntent .setType("plain/text"); 
			emailIntent .putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"boodweb@gmail.com"});     
			emailIntent .putExtra(android.content.Intent.EXTRA_SUBJECT, title);     
			//emailIntent .putExtra(android.content.Intent.EXTRA_TEXT, yourBodyText);     
			startActivity(Intent.createChooser(emailIntent, "Send mail..."));
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}
	
	private void showUsage() {
		String usage = String.format(getString(R.string.usage_content), getString(R.string.app_name), mGlobalData.getVersionName());
		AlertDialog dialog = new AlertDialog.Builder(this).setTitle(getString(R.string.usage))
				.setMessage(usage)
				.setPositiveButton(getString(R.string.close), null).show();
		TextView textView = (TextView) dialog.findViewById(android.R.id.message);
		textView.setTextSize(15);
	}
}
